home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / gould-pinsn.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  7KB  |  295 lines

  1. /* Print GOULD RISC instructions for GDB, the GNU debugger.
  2.    Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "gdbcore.h"
  22.  
  23. #include "defs.h"
  24. #include "param.h"
  25. #include "symtab.h"
  26. #include "frame.h"
  27. #if defined GOULD_PN
  28. #include "pn-opcode.h"
  29. #else
  30. #include "np1-opcode.h"
  31. #endif
  32.  
  33. /* GOULD RISC instructions are never longer than this many bytes.  */
  34. #define MAXLEN 4
  35.  
  36. /* Number of elements in the opcode table.  */
  37. #define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
  38.  
  39.  
  40. /* Print the GOULD instruction at address MEMADDR in debugged memory,
  41.    on STREAM.  Returns length of the instruction, in bytes.  */
  42.  
  43. int
  44. print_insn (memaddr, stream)
  45.     CORE_ADDR memaddr;
  46.     FILE *stream;
  47. {
  48.     unsigned char buffer[MAXLEN];
  49.     register int i;
  50.     register char *d;
  51.     register int bestmask;
  52.     unsigned best;
  53.     int temp, index, bestlen;
  54.  
  55.     read_memory (memaddr, buffer, MAXLEN);
  56.  
  57.     bestmask = 0;
  58.     index = -1;
  59.     best = 0xffffffff;
  60.     for (i = 0; i < NOPCODES; i++)
  61.     {
  62.         register unsigned int opcode = gld_opcodes[i].opcode;
  63.         register unsigned int mask = gld_opcodes[i].mask;
  64.         register unsigned int len = gld_opcodes[i].length;
  65.         register unsigned int test;
  66.  
  67.         /* Get possible opcode bytes into integer */
  68.         test = buffer[0] << 24;
  69.         test |= buffer[1] << 16;
  70.         test |= buffer[2] << 8;
  71.         test |= buffer[3];
  72.  
  73.         /* Mask with opcode and see if match */
  74.         if ((opcode & mask) == (test & mask))
  75.         {
  76.             /* See if second or third match */
  77.             if (index >= 0)
  78.             {
  79.                 /* Take new one if it looks good */
  80.                 if (bestlen == MAXLEN && len == MAXLEN)
  81.                 {
  82.                     /* See if lower bits matched */
  83.                     if (((bestmask & 3) == 0) &&
  84.                         ((mask & 3) != 0))
  85.                     {
  86.                         bestmask = mask;
  87.                         bestlen = len;
  88.                         best = test;
  89.                         index = i;
  90.                     }
  91.                 }
  92.             }
  93.             else
  94.             {
  95.                 /* First match, save it */
  96.                 bestmask = mask;
  97.                 bestlen = len;
  98.                 best = test;
  99.                 index = i;
  100.             }
  101.         }
  102.     }
  103.  
  104.     /* Handle undefined instructions.  */
  105.     if (index < 0)
  106.     {
  107.         fprintf (stream, "undefined   0%o",(buffer[0]<<8)+buffer[1]);
  108.         return 2;
  109.     }
  110.  
  111.     /* Print instruction name */
  112.     fprintf (stream, "%-12s", gld_opcodes[index].name);
  113.  
  114.     /* Adjust if short instruction */
  115.     if (gld_opcodes[index].length < 4)
  116.     {
  117.         best >>= 16;
  118.         i = 0;
  119.     }
  120.     else
  121.     {
  122.         i = 16;
  123.     }
  124.  
  125.     /* Dump out instruction arguments */
  126.       for (d = gld_opcodes[index].args; *d; ++d)
  127.     {
  128.         switch (*d)
  129.         {
  130.         case 'f':
  131.             fprintf (stream, "%d",  (best >> (7 + i)) & 7);
  132.             break;
  133.         case 'r':
  134.             fprintf (stream, "r%d", (best >> (7 + i)) & 7);
  135.             break;
  136.         case 'R':
  137.             fprintf (stream, "r%d", (best >> (4 + i)) & 7);
  138.             break;
  139.         case 'b':
  140.             fprintf (stream, "b%d", (best >> (7 + i)) & 7);
  141.             break;
  142.         case 'B':
  143.             fprintf (stream, "b%d", (best >> (4 + i)) & 7);
  144.             break;
  145.         case 'v':
  146.             fprintf (stream, "b%d", (best >> (7 + i)) & 7);
  147.             break;
  148.         case 'V':
  149.             fprintf (stream, "b%d", (best >> (4 + i)) & 7);
  150.             break;
  151.         case 'X':
  152.             temp = (best >> 20) & 7;
  153.             if (temp)
  154.             fprintf (stream, "r%d", temp);
  155.             else
  156.             putc ('0', stream);
  157.             break;
  158.         case 'A':
  159.             temp = (best >> 16) & 7;
  160.             if (temp)
  161.             fprintf (stream, "(b%d)", temp);
  162.             break;
  163.         case 'S':
  164.             fprintf (stream, "#%d", best & 0x1f);
  165.             break;
  166.         case 'I':
  167.             fprintf (stream, "#%x", best & 0xffff);
  168.             break;
  169.         case 'O':
  170.             fprintf (stream, "%x", best & 0xffff);
  171.             break;
  172.         case 'h':
  173.             fprintf (stream, "%d", best & 0xfffe);
  174.             break;
  175.         case 'd':
  176.             fprintf (stream, "%d", best & 0xfffc);
  177.             break;
  178.         case 'T':
  179.             fprintf (stream, "%d", (best >> 8) & 0xff);
  180.             break;
  181.         case 'N':
  182.             fprintf (stream, "%d", best & 0xff);
  183.             break;
  184.         default:
  185.             putc (*d, stream);
  186.             break;
  187.         }
  188.     }
  189.  
  190.     /* Return length of instruction */
  191.       return (gld_opcodes[index].length);
  192. }
  193.  
  194. /*
  195.  * Find the number of arguments to a function.
  196.  */
  197. findarg(frame)
  198.     struct frame_info *frame;
  199. {
  200.     register struct symbol *func;
  201.     register unsigned pc;
  202.  
  203. #ifdef notdef
  204.     /* find starting address of frame function */
  205.     pc = get_pc_function_start (frame->pc);
  206.  
  207.     /* find function symbol info */
  208.     func = find_pc_function (pc);
  209.  
  210.     /* call blockframe code to look for match */
  211.     if (func != NULL)
  212.                 return (func->value.block->nsyms / sizeof(int));
  213. #endif
  214.  
  215.         return (-1);
  216.  
  217. /*
  218.  * In the case of the NPL, the frame's norminal address is Br2 and the 
  219.  * previous routines frame is up the stack X bytes.  Finding out what
  220.  * 'X' is can be tricky.
  221.  *
  222.  *    1.) stored in the code function header xA(Br1).
  223.  *    2.) must be careful of recurssion.
  224.  */
  225. FRAME_ADDR
  226. findframe(thisframe)
  227.     FRAME thisframe;
  228. {
  229.     register FRAME_ADDR pointer;
  230.     FRAME_ADDR framechain();
  231. #if 0    
  232.     struct frame_info *frame;
  233.  
  234.     /* Setup toplevel frame structure */
  235.     frame->pc = read_pc();
  236.     frame->next_frame = 0;
  237.     frame->frame = read_register (SP_REGNUM);    /* Br2 */
  238.  
  239.     /* Search for this frame (start at current Br2) */
  240.     do
  241.     {
  242.     pointer = framechain(frame);
  243.     frame->next_frame = frame->frame;
  244.     frame->frame = pointer;
  245.     frame->pc = FRAME_SAVED_PC(frame);
  246.     }
  247.     while (frame->next_frame != thisframe);
  248. #endif
  249.  
  250.     pointer = framechain (thisframe);
  251.  
  252.     /* stop gap for now, end at __base3 */
  253.     if (thisframe->pc == 0)
  254.     return 0;
  255.  
  256.     return pointer;
  257. }
  258.  
  259. /*
  260.  * Gdb front-end and internal framechain routine.
  261.  * Go back up stack one level.  Tricky...
  262.  */
  263. FRAME_ADDR
  264. framechain(frame)
  265.     register struct frame_info *frame;
  266. {
  267.     register CORE_ADDR func, prevsp;
  268.     register unsigned value;
  269.  
  270.     /* Get real function start address from internal frame address */
  271.     func = get_pc_function_start(frame->pc);
  272.  
  273.     /* If no stack given, read register Br1 "(sp)" */
  274.     if (!frame->frame)
  275.     prevsp = read_register (SP_REGNUM);
  276.     else
  277.     prevsp = frame->frame;
  278.  
  279.     /* Check function header, case #2 */
  280.     value = read_memory_integer (func, 4);
  281.     if (value)
  282.     {
  283.     /* 32bit call push value stored in function header */
  284.     prevsp += value;
  285.     }
  286.     else
  287.     {
  288.     /* read half-word from suabr at start of function */
  289.     prevsp += read_memory_integer (func + 10, 2);
  290.     }
  291.  
  292.     return (prevsp);
  293. }
  294.